package com.qianfeng.myannotationdemo.annotation;

import android.app.Activity;
import android.view.View;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Created by jackiechan on 16/3/6 下午3:27.
 * 版本: 1
 * 公司:北京千锋互联科技有限公司
 */
public class ViewInjectImpl implements ViewInjectUtils{
    private static ViewInjectImpl viewInject = new ViewInjectImpl();

    private ViewInjectImpl() {

    }

    public static ViewInjectImpl getInstance() {
        return viewInject;
    }

    public void inject(Activity activity) {
        Class<? extends Activity> aClass = activity.getClass();//首先获取类的字节码
        ContenView annotation = getContenView(aClass);//获取这个类身上的注解
        if (annotation == null) {

        } else {//代表有当前 activity 上面有这个注解
            int valye = annotation.value();//获取注解内部的值
            try {
                Method setContentView = aClass.getMethod("setContentView", int.class);//按照参数名和参数类型获取指定的方法
            //    activity.setContentView(valye);//等同于下面
                setContentView.invoke(activity, valye);//调用对应的方法,第一个参数, 调用哪个对象里面的这个方法,第二个参数  是方法的参数
                // findViewbyID
                findView(aClass, activity);//findviewbyid
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }


    private void findView(Class clazz, Activity activity) {
        try {
            //首先应该获取到所有的变量,然后看看它身上有没有对应的注解,有 就解析,没有就略过
            Field[] declaredFields = clazz.getDeclaredFields();//获取所有的变量,包括私有
            for (Field declaredField : declaredFields) {//Bianli//判断是不是View, 是不是静态,是不是 final
                ViewInject annotation = declaredField.getAnnotation(ViewInject.class);// 获取变量身上的注解
                if (annotation != null) {
                    int id = annotation.value();//获取到 findviewbyid 的具体的 id
                    View viewById = activity.findViewById(id);//找到对应的 view
                    declaredField.setAccessible(true);//设置变量属性为允许访问修改
                    declaredField.set(activity, viewById);//给这个变量赋值,第一个参数,还是哪个对象里面的变量值,第二个参数,要将什么值赋给这个变量
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
//  clazz.getFields();//获取所有的非 private 变量
    }


    /**
     * 获取 setcontentview 的注解
     *
     * @param clazz
     * @return
     */
    private ContenView getContenView(Class clazz) {
        ContenView annotation = null;
        if (clazz == null) {
            return null;
        } else {
            annotation = (ContenView) clazz.getAnnotation(ContenView.class);//从 activiy 中获取ContenView的注解
            if (annotation == null) {
                annotation = getContenView(clazz.getSuperclass());//如果当前类上面没有这个注解,从父类获取
            }
        }
        return annotation;//返回注解
    }
}
